package com.richpay.landiprintdemo.print;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.Log;


import com.landicorp.android.eptapi.device.Printer;

import com.landicorp.android.eptapi.device.Printer.Format;
import com.landicorp.android.eptapi.exception.RequestException;
import com.landicorp.android.eptapi.utils.QrCode;
import com.richpay.landiprintdemo.data.TransData;
import com.richpay.landiprintdemo.data.TransType;
import com.richpay.landiprintdemo.utils.DateUtil;
import com.richpay.landiprintdemo.utils.SignBitmapUtil;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import static com.landicorp.android.eptapi.device.Printer.Format.HZ_DOT16x16;
import static com.landicorp.android.eptapi.device.Printer.Format.HZ_DOT24x24;
import static com.landicorp.android.eptapi.utils.QrCode.ECLEVEL_Q;

/**
 * 打印机 根据设备来 A8
 */
public class PrinterImpl {
    private Context context;
    private Printer.Progress progress;
    private List<Printer.Step> stepList;
    private Printer.Alignment alignment;//对齐方式
    private LanDiPrinter.PrinterListener listener;

    public void setListener(LanDiPrinter.PrinterListener listener) {
        this.listener = listener;
    }

    public PrinterImpl(Context context) {
        this.context = context;
    }

    /**
     * @return 返回打印机状态
     */
    public int getPrinterStatus() {
        try {
            return Printer.getInstance().getStatus();
        } catch (RequestException e) {
            e.printStackTrace();
        }
        //返回错误
        if (listener != null) {
            listener.onError("打印机状态异常!");

        }
        return PrinterError.FAIL;
    }

    /**
     * 初始化打印数据集合
     */
    public void init() {
        stepList = new ArrayList<>();
    }

    /**
     * @return 添加文字
     */
    public boolean addText(final TransData transData, final int type, final boolean isRePrint) {
        if (stepList == null) {
            Log.e("PrinterImpl", "please invoking init() firstly");
            return false;
        }
        stepList.add(new Printer.Step() {
            @Override
            public void doPrint(Printer printer) throws Exception {
                printer.setAutoTrunc(false);
                Format format = new Format();
                format.setAscScale(Printer.Format.ASC_SC1x2);//英文字体缩放大小
                format.setAscSize(Printer.Format.ASC_DOT24x12);//英文字体点阵大小
                format.setHzScale(Format.HZ_SC1x2);//汉字字体缩放大小
                format.setHzSize(HZ_DOT24x24);//汉字字体点阵大小
                printer.setFormat(format);
                printer.printMid("银联POS签购单\n");
                String temp;
                Log.d("PRINT", "【type=" + type + ",isRePrint=" + isRePrint + "】" + transData.toString());
                if (type == 1) {
                    temp = "商户存根";
                } else {
                    temp = "持卡人存根";
                }
//                alignment = Printer.Alignment.CENTER;
//                printer.printText(alignment, "福建联迪商用设备有限公司\n");
//                printer.printText(alignment, "www.landicorp.com\n");
                format.setAscScale(Format.ASC_SC1x1);
                format.setAscSize(Format.ASC_DOT16x8);
                format.setHzScale(Format.HZ_SC1x1);
                format.setHzSize(HZ_DOT16x16);
                printer.printMixText(format, "- - - - - - - - - - - - - - - - - - - - - - - - - -\n");

                //刷卡类
                if (transData.getTransType().equals(TransType.SALE.getType())
                        || transData.getTransType().equals(TransType.SALE_REFUND.getType())
                        || transData.getTransType().equals(TransType.SALE_REVOKE.getType())
                        || transData.getTransType().equals(TransType.AUTH.getType())
                        || transData.getTransType().equals(TransType.AUTH_COMPLETE.getType())
                        || transData.getTransType().equals(TransType.AUTH_COMPLETE_REVOKE.getType())
                        || transData.getTransType().equals(TransType.AUTH_REVOKE.getType())
                        ) {

                    format.setAscScale(Format.ASC_SC1x1);
                    format.setAscSize(Format.ASC_DOT24x12);
                    format.setHzScale(Format.HZ_SC1x1);
                    format.setHzSize(HZ_DOT24x24);
                    printer.printMixText(format, "商户名称:" + transData.getMerchantName() + "\n");
                    printer.printMixText(format, "商户编号:" + transData.getMerchantNo() + "\n");
                    printer.printMixText(format, "终端编号:" + transData.getTerminalNo() + "\n");

                    format.setAscScale(Format.ASC_SC1x1);
                    format.setAscSize(Format.ASC_DOT16x8);
                    format.setHzScale(Format.HZ_SC1x1);
                    format.setHzSize(HZ_DOT16x16);
                    printer.printMixText(format, "- - - - - - - - - - - - - - - - - - - - - - - - - -\n");

                    format.setAscScale(Format.ASC_SC1x1);
                    format.setAscSize(Format.ASC_DOT24x12);
                    format.setHzScale(Format.HZ_SC1x1);
                    format.setHzSize(HZ_DOT24x24);
                    printer.printMixText(format, "发卡行:" + getBankName(transData.getIssNo()) + "\n");

                    format.setAscScale(Printer.Format.ASC_SC1x2);//英文字体缩放大小
                    format.setAscSize(Printer.Format.ASC_DOT24x12);//英文字体点阵大小
                    format.setHzScale(Format.HZ_SC1x2);//汉字字体缩放大小
                    format.setHzSize(HZ_DOT24x24);//汉字字体点阵大小
                    if (transData.getTransType().equals(TransType.AUTH.getType())) {//预授权
                        printer.printMixText(format, "卡   号:" + transData.getCardNo() + "\n");
                    } else {
                        printer.printMixText(format, "卡   号:" + getSecretNumber(transData.getCardNo()) + "\n");
                    }

                    format.setAscScale(Format.ASC_SC1x1);
                    format.setAscSize(Format.ASC_DOT24x12);
                    format.setHzScale(Format.HZ_SC1x1);
                    format.setHzSize(HZ_DOT24x24);
                    printer.printMixText(format, "交易类型:" + transData.getTransType() + "\n");
                    if (transData.getTransType().equals(TransType.AUTH.getType())) {//预授权
                        printer.printMixText(format, "有效期:" + transData.getCardExpiryDate() + "   授权码:" + transData.getAuthNo() + "\n");
                    }
                    printer.printMixText(format, "批次号:" + transData.getBatchNo() + " 凭证号:" + transData.getVoucherNo() + "\n");
                    printer.printMixText(format, "参考号:" + transData.getReferNo() + "\n");
                    printer.printMixText(format, "日期时间:" + transData.getOrderDate() + " " + transData.getOrderTime() + "\n");

                    format.setAscScale(Printer.Format.ASC_SC1x2);//英文字体缩放大小
                    format.setAscSize(Printer.Format.ASC_DOT24x12);//英文字体点阵大小
                    format.setHzScale(Format.HZ_SC1x2);//汉字字体缩放大小
                    format.setHzSize(HZ_DOT24x24);//汉字字体点阵大小
                    printer.printMixText(format, "金   额: RMB " + transData.getAmount() + "\n");

                    format.setAscScale(Format.ASC_SC1x1);
                    format.setAscSize(Format.ASC_DOT24x12);
                    format.setHzScale(Format.HZ_SC1x1);
                    format.setHzSize(HZ_DOT24x24);
                    printer.printMixText(format, "统一商户号:" + "10001000100" + "\n");
                    printer.printMixText(format, "统一终端号:" + "01" + " 操作员:01" + "\n");

                    format.setAscScale(Format.ASC_SC1x1);
                    format.setAscSize(Format.ASC_DOT16x8);
                    format.setHzScale(Format.HZ_SC1x1);
                    format.setHzSize(HZ_DOT16x16);
                    printer.printMixText(format, "- - - - - - - - - - - - - - - - - - - - - - - - - -\n");
                    String singData = transData.getSignData();
                    if (singData != null && singData.length() > 0) {
                        //  addBitmap();
                        printer.printMixText(format, "持卡人签名:\n");
                        // printer.feedLine(1);
                        //addBitmap();
                        printer.printImageNew(Printer.Alignment.CENTER, SignBitmapUtil.generateByte(singData));
                        //addBitmap(SignBitmapUtil.getImagePath());
//                        addBitmap(SignBitmapUtil.generateByte(singData));

                    } else {
                        printer.printMixText(format, "交易未满1000元，免密免签\n");
                    }
                    printer.printMixText(format, "本人确认以上交易，同意将其记入本卡账户\n");
                    printer.printMixText(format, "程序版本:A8 " + packageName(context) + "   " + temp + "\n");
                    if (isRePrint) {
                        printer.printMixText(format, "重打印 " + DateUtil.getOrderDate() + " " + DateUtil.getOrderTime() + "\n");
                    }
                    printer.feedLine(2);
                    //   printer.cutPaper();
                }


                //扫码

                if (transData.getTransType().equals(TransType.QR_SALE.getType())
                        || transData.getTransType().equals(TransType.QR_REVOKE.getType())
                        || transData.getTransType().equals(TransType.QR_REFUND.getType())

                        || transData.getTransType().equals(TransType.QR_AUTH_CM.getType())
                        || transData.getTransType().equals(TransType.QR_AUTH_CM_REVOKE.getType())
                        || transData.getTransType().equals(TransType.QR_AUTH_REVOKE.getType())
                        || transData.getTransType().equals(TransType.QR_AUTH.getType())) {//扫码类


                    format.setAscScale(Format.ASC_SC1x1);
                    format.setAscSize(Format.ASC_DOT24x12);
                    format.setHzScale(Format.HZ_SC1x1);
                    format.setHzSize(HZ_DOT24x24);
                    printer.printMixText(format, "商户名称:" + transData.getMerchantName() + "\n");
                    printer.printMixText(format, "商户编号:" + transData.getMerchantNo() + "\n");
                    printer.printMixText(format, "终端编号:" + transData.getTerminalNo() + "\n");


                    format.setAscScale(Format.ASC_SC1x1);
                    format.setAscSize(Format.ASC_DOT16x8);
                    format.setHzScale(Format.HZ_SC1x1);
                    format.setHzSize(HZ_DOT16x16);
                    printer.printMixText(format, "- - - - - - - - - - - - - - - - - - - - - - - - - -\n");

                    format.setAscScale(Format.ASC_SC1x1);
                    format.setAscSize(Format.ASC_DOT24x12);
                    format.setHzScale(Format.HZ_SC1x1);
                    format.setHzSize(HZ_DOT24x24);
                    printer.printMixText(format, "支付方式:" + transData.getPayType() + "\n");
                    if (transData.getCardNo() != null) {
                        printer.printMixText(format, "付 款 码:" + getSecretNumber(transData.getCardNo()) + "\n");
                    }
                    printer.printMixText(format, "交易类型:" + transData.getTransType() + "\n");
                    printer.printMixText(format, "日期时间:" + transData.getOrderDate() + " " + transData.getOrderTime() + "\n");
                    if (transData.getTransType().equals(TransType.QR_REVOKE.getType())
                            || transData.getTransType().equals(TransType.QR_REFUND.getType())
                            || transData.getTransType().equals(TransType.QR_AUTH_CM_REVOKE.getType())
                            || transData.getTransType().equals(TransType.QR_AUTH_REVOKE.getType())) {
                        printer.printMixText(format, "原订单号:" + "\n");
                        printer.printMixText(format, transData.getOrigOrderId() + "\n");
                    }
                    format.setAscScale(Printer.Format.ASC_SC1x2);//英文字体缩放大小
                    format.setAscSize(Printer.Format.ASC_DOT24x12);//英文字体点阵大小
                    format.setHzScale(Format.HZ_SC1x2);//汉字字体缩放大小
                    format.setHzSize(HZ_DOT24x24);//汉字字体点阵大小
                    printer.printMixText(format, "金   额: RMB " + transData.getAmount() + "\n");
                    if (transData.getTransType().equals(TransType.QR_SALE.getType())//普通扫码
                            || transData.getTransType().equals(TransType.QR_AUTH.getType())//扫码预授权
                            || transData.getTransType().equals(TransType.QR_AUTH_CM.getType())) {//扫码预授权完成

                        if (transData.getTransType().equals(TransType.QR_SALE.getType())//普通扫码
                                || transData.getTransType().equals(TransType.QR_REVOKE.getType())
                                || transData.getTransType().equals(TransType.QR_REFUND.getType())) {
                            printer.printQrCode(Printer.Alignment.CENTER, new QrCode(getScanType(transData.getPayType()) + "|" + transData.getAmount() + "|" + transData.getOrderId(), ECLEVEL_Q), 200);
                        } else if (transData.getTransType().equals(TransType.QR_AUTH.getType())) {//扫码预授权
                            printer.printQrCode(Printer.Alignment.CENTER, new QrCode(getScanType(transData.getPayType()) + "|" + transData.getAmount() + "|" + transData.getVoucherNo(), ECLEVEL_Q), 200);
                        } else if (transData.getTransType().equals(TransType.QR_AUTH_CM.getType())) {//扫码预授权完成
                            printer.printQrCode(Printer.Alignment.CENTER, new QrCode(getScanType(transData.getPayType()) + "|" + transData.getAmount() + "|" + transData.getVoucherNo(), ECLEVEL_Q), 200);
                        }
                        // 走纸
                        format.setAscScale(Format.ASC_SC1x1);
                        format.setAscSize(Format.ASC_DOT16x8);
                        format.setHzScale(Format.HZ_SC1x1);
                        format.setHzSize(HZ_DOT16x16);
                        printer.printMixText(format, "可凭以上二维码到支持的商户退款\n");
                    }
                    format.setAscScale(Format.ASC_SC1x1);
                    format.setAscSize(Format.ASC_DOT24x12);
                    format.setHzScale(Format.HZ_SC1x1);
                    format.setHzSize(HZ_DOT24x24);
                    printer.printMixText(format, "统一商户号:" + "" + "\n");
                    printer.printMixText(format, "统一终端号:" + "" + " 操作员:01" + "\n");

                    format.setAscScale(Format.ASC_SC1x1);
                    format.setAscSize(Format.ASC_DOT16x8);
                    format.setHzScale(Format.HZ_SC1x1);
                    format.setHzSize(HZ_DOT16x16);
                    printer.printMixText(format, "- - - - - - - - - - - - - - - - - - - - - - - - - -\n");

                    printer.printMixText(format, "本人确认以上交易，同意将其记入本卡账户\n");
                    printer.printMixText(format, "程序版本:A8 " + packageName(context) + "   " + temp + "\n");
                    if (isRePrint) {
                        printer.printMixText(format, "重打印 " + DateUtil.getOrderDate() + " " + DateUtil.getOrderTime() + "\n");
                    }
                    printer.feedLine(2);
                }
            }
        });
        return true;
    }

    /**
     * 添加图片
     *
     * @return
     */
    public boolean addBitmap() {
        if (stepList == null) {
            Log.e("PrinterImpl", "please invoking init() firstly");
            return false;
        }
        Log.e("AAA", "addBitmap");

        stepList.add(new Printer.Step() {
            @Override
            public void doPrint(Printer printer) {
                Log.e("AAA", "doPrint");

                InputStream inputStream = null;
                try {
                    inputStream = new FileInputStream(SignBitmapUtil.getImagePath());
                    printer.printImage(Printer.Alignment.CENTER, inputStream);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                    Log.e("AAA", e.getMessage());
                } catch (Exception e) {
                    e.printStackTrace();
                    Log.e("AAA", e.getMessage());
                }
            }
        });
        return true;
    }

    public boolean addBitmap(String imagePath) {

        if (stepList == null) {
            Log.e("PrinterImpl", "please invoking init() firstly");
            return false;
        }

        stepList.add(new Printer.Step() {
            @Override
            public void doPrint(Printer printer) throws Exception {
                printer.printMonochromeBmp(384, SignBitmapUtil.getImagePath());
            }
        });
        return true;
    }

    public boolean addBitmap(final byte[] bitmapData) {
        if (stepList == null) {
            Log.e("PrinterImpl", "please invoking init() firstly");
            return false;
        }

        stepList.add(new Printer.Step() {
            @Override
            public void doPrint(Printer printer) throws Exception {
                printer.printImageNew(Printer.Alignment.CENTER, bitmapData);
            }
        });
        return true;
    }

    /**
     * 条形码
     *
     * @return
     */
    public boolean addBarcode() {
        if (stepList == null) {
            Log.e("PrinterImpl", "please invoking init() firstly");
            return false;
        }
        stepList.add(new Printer.Step() {
            @Override
            public void doPrint(Printer printer) throws Exception {
                printer.printBarCode("1234567890");
            }
        });
        return true;
    }

    /**
     * @return 二维码
     */
    public boolean addQRcode(final String content) {
        if (stepList == null) {
            Log.e("PrinterImpl", "please invoking init() firstly");
            return false;
        }
        stepList.add(new Printer.Step() {
            @Override
            public void doPrint(Printer printer) throws Exception {
                printer.printQrCode(Printer.Alignment.CENTER, new QrCode(content, ECLEVEL_Q), 200);
            }
        });
        return true;
    }

    /**
     * 走纸
     *
     * @param line
     * @return
     */
    public boolean feedLine(final int line) {
        if (stepList == null) {
            Log.e("PrinterImpl", "please invoking init() firstly");
            return false;
        }
        stepList.add(new Printer.Step() {
            @Override
            public void doPrint(Printer printer) throws Exception {
                printer.feedLine(line);
            }
        });
        return true;
    }

    /**
     * 裁剪线
     *
     * @return
     */
    public boolean cutPage() {
        if (stepList == null) {
            Log.e("PrinterImpl", "please invoking init() firstly");
            return false;
        }
        stepList.add(new Printer.Step() {
            @Override
            public void doPrint(Printer printer) throws Exception {
                printer.cutPaper();
            }
        });
        return true;
    }

    public void startPrint() {
        if (stepList == null) {
            Log.e("PrinterImpl", "please invoking init() firstly");
            return;
        }
        if (listener != null) {
            listener.onPrintStart();
        }
        progress = new Printer.Progress() {
            @Override
            public void doPrint(Printer prn) throws Exception {
                //
            }

            @Override
            public void onFinish(int error) {
                stepList.clear();
                if (error == Printer.ERROR_NONE) {
                    Log.e("PrinterImpl", "please invoking init() firstly");
                    if (listener != null) {
                        listener.onFinish();
                    }
                } else {
                    String errorDes = Printer.getErrorDescription(error);
                    Log.e("PrinterImpl", "打印出错：" + errorDes);

                    if (listener != null) {
                        listener.onError(errorDes);
                    }
                }
            }

            @Override
            public void onCrash() {
                stepList.clear();
                // onDeviceServiceCrash();
                if (listener != null) {
                    listener.onError("打印机出现异常!");
                }
            }
        };

        for (Printer.Step step : stepList) {
            progress.addStep(step);
        }

        try {
            progress.start();
        } catch (RequestException e) {
            e.printStackTrace();
        }
    }


    public static String packageName(Context context) {
        PackageManager manager = context.getPackageManager();
        String name = null;
        try {
            PackageInfo info = manager.getPackageInfo(context.getPackageName(), 0);
            name = info.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return name;
    }


    private String getScanType(String type) {
        if (type.equals("微信")) {
            return "1";
        } else if (type.equals("支付宝")) {
            return "2";
        } else {
            return "3";
        }
    }


    private String getSecretNumber(String origin) {
        if (origin != null && origin.length() > 8) {
            String header = origin.substring(0, 4);
            String footer = origin.substring(origin.length() - 4, origin.length());
            return header + " ****** " + footer;
        } else {
            return "0";
        }

    }

    public static String getFormatBill(String bill) {
        int len = bill.length();
        if (len == 1) {
            return "   " + bill;
        }

        if (len == 2) {
            return "  " + bill;
        }
        if (len == 3) {
            return " " + bill;
        }
        if (len == 4) {
            return "" + bill;
        }
        return bill;
    }

    private String getSTbyType(String string) {
        if (string.equals(TransType.SALE.getType())) {
            return "S";
        } else if (string.equals(TransType.SALE_REVOKE.getType())) {
            return "V";
        } else if (string.equals(TransType.SALE_REFUND.getType())) {
            return "R";
        } else if (string.equals(TransType.QR_SALE.getType())
                || string.equals(TransType.QR_AUTH_CM.getType())
                || string.equals(TransType.QR_AUTH.getType())) {
            return "Q";
        } else if (string.equals(TransType.QR_REVOKE.getType())
                || string.equals(TransType.QR_AUTH_REVOKE.getType())
                || string.equals(TransType.QR_AUTH_CM_REVOKE.getType())
                ) {
            return "D";
        } else if (string.equals(TransType.AUTH_COMPLETE.getType())) {
            return "P";
        } else if (string.equals(TransType.AUTH_COMPLETE_REVOKE.getType())) {
            return "A";
        } else if (string.equals(TransType.QR_REFUND.getType())) {
            return "F";
        } else {
            return "N";
        }
    }


    private static String[][] bankNames = {
            {"0102", "工商银行", "工行 银联",},
            {"0103", "农业银行", "农行 银联"},
            {"0104", "中国银行", "中行 银联"},
            {"0105", "建设银行", "建行 银联"},
            {"0100", "邮储银行", "邮储 银联"},
            {"0301", "交通银行", "交行 银联"},
            {"0302", "中信银行", "中信 银联"},
            {"0303", "光大银行", "光大 银联"},
            {"0304", "华夏银行", "华夏 银联"},
            {"0305", "民生银行", "民生 银联"},
            {"0306", "广发银行", "广发 银联"},
            {"0307", "深发银行", "深发 银联"},
            {"0308", "招商银行", "招行 银联"},
            {"0309", "兴业银行", "兴业 银联"},
            {"0310", "浦发银行", "浦发 银联"},
            {"0311", "恒丰银行", "恒丰 银联"},
            {"1429", "浙江农信", "浙农 银联"},
            {"4802", "银联商务", "银联 商务"},};

    /**
     * 通过银行ID获取银行名称
     *
     * @param bankId
     * @return
     */
    private String getBankName(String bankId) {

        if (bankId == null || bankId.length() < 4) {

            return bankId;
        }

        String subBankId = bankId.substring(0, 4);

        for (int i = 0; i < bankNames.length; i++) {
            if (bankNames[i][0].equals(subBankId)) {
                return bankNames[i][1];
            }
        }
        return bankId;
    }
}
